package com.jinlia.show.modules.base.utils;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
 * 付款单生成器
 */
public class PayOrderNumGenerator {

    private final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyMMddHHmmss"); // 2525年6月1日00:00:00
    private final LocalDateTime startLocalDateTime = LocalDateTime.of(2025, 6, 1, 0, 0, 0);
    private LocalDateTime lastLocalDateTime;

    private final int maxSequence = 9; // 最大序列号（0-999，共1000个）
    private int currentSequence = 0;     // 当前序列号

    public PayOrderNumGenerator() {
        this.lastLocalDateTime = startLocalDateTime;
    }

    public synchronized String nextId() {
        LocalDateTime now = LocalDateTime.now();
        // 检查时钟回拨
        if (now.isBefore(lastLocalDateTime)) {
            throw new RuntimeException(
                    String.format("Clock moved backwards. Refusing to generate id. Last time: %s, Current time: %s",
                            lastLocalDateTime, now)
            );
        }

        // 如果当前时间等于最后记录时间，则递增序列号
//        if ( now.compareTo(lastLocalDateTime) == 0){ //包含毫秒值
        if (formatter.format(now).equals(formatter.format(lastLocalDateTime))) {
            currentSequence++;
            if (currentSequence > maxSequence) {
                // 序列号用尽，等待下一毫秒
                now = tilNextMillis(lastLocalDateTime);
                currentSequence = 0; // 重置序列号
            }
        } else {
            // 时间变化，重置序列号
            currentSequence = 0;
        }
        lastLocalDateTime = now;
        return String.format("P%s%s", formatter.format(lastLocalDateTime), currentSequence);
    }

    /**
     * 等待直到下一毫秒
     */
    protected LocalDateTime tilNextMillis(LocalDateTime lastLocalDateTime) {
        LocalDateTime now;
        do {
            now = LocalDateTime.now();
        } while (formatter.format(now).equals(formatter.format(lastLocalDateTime)));

        return now;
    }

    public static void main(String[] args) {
        PayOrderNumGenerator idGenerator = new PayOrderNumGenerator();
        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                for (int j = 0; j < 100; j++) {
                    System.out.println(Thread.currentThread().getName()+idGenerator.nextId());
                }
            }).start();
//            System.out.println(Thread.currentThread().getName()+idGenerator.nextId());
        }
    }
}
